The basic differences are:
$form['field_name']['#access'] = FALSE;
hides the form element. When saving the form Drupal will not touch the field. That means the initial value will remain. Maybe interesting: Other users can do with that node's field what ever they want. You saving the node will not undo their changes, although you only know about the old value of that field.
hide($form['picture']);
is afaik used in theme functions only. It can cause forms to break because after saving a form this field is expected to have a value but is not even rendered. So use this with care. When you hide a field that is important make sure to manually render it later. Calling hide will also hide all child elements of the element you hide. A use case could be: Render child elements of a form manully and call hide
on those elements. When you now render the parent element only those child elements are rendered that did not go through hide.
unset($form['picture']);
should not be used. It just drops parts of an array. It is better to use one of the other three functions that keep the data consistent and not delete stuff Drupal expects.
$form['account']['mail']['#disabled'] = TRUE;
will not hide the element but just make it unchangable (greyed dropdowns, etc.). It acts like a normal field but the initial value cannot be changed by the user.
In addition to what you asked, Clive added something:
Form elements are commonly converted to array('#type' => 'value', '#value' => 'foo')
to remove them from the form but keep them server side, and not mess up the submission process. It's the best of all available methods IMO
Hope that help although I am not completely sure about the consequences of unset.
cheers,
j