W sumie najlepiej całość opisał prgtw - obydwie te właściwości służą do innych celów.
Display ustawia sposób wyświetlania. Jedną z możliwych sposobów wyświetlania, jest nie wyświetlanie w ogóle. Do tego służy display: none. Wliczam w sposób wyświetlania również sposób pozycjonowania danego elementu i jego wpływu na elementy sąsiednie.
Visibility decyduje o tym, czy obiekt jest widoczny, czy nie. Jednak nie wpływa na to, jak się zachowuje reszta elementów na stronie.
W praktyce - jeśli chcesz ukryć jakiś fragment strony, to zadaj sobie pytanie, jak chcesz, by zachowała się reszta. Jeśli przykładowo "zwijasz" jakiś akapit w tekście (jakieś rozszerzenie, przypisy czy tym podobne), to najczęściej display: none jest tutaj adekwatną właściwością. Jeśli jednak chowasz na przykład jakiś element designu, fragment menu (tutaj to już różnie) czy tym podobne - często zależy nam na tym, by element był niewidoczny, ale jego pojawianie się i znikanie nie wpływało na resztę strony. W takiej sytuacji użycie display: none/jakiśtam jest niewłaściwe, czasem może wręcz doprowadzić do "rozjechania się" strony. Wówczas najlepiej użyć visibility: hidden.
Jeśli pozostawianie miejsca z jakichś powodów jest nieistotne (może zostawiać, może nie, nie wpływa to na wygląd), wówczas wydaje mi się, że visibility jest bliższe semantycznie temu, co chcemy osiągnąć poprzez ukrywanie elementu.