Indeed, there is a way to define one term per taxonomy as default term which makes it non-deletable from the admin GUI.
WP_Terms_List_Table looks for an option
get_option( 'default_' . $this->screen->taxonomy ).
So if you have a custom Taxonomy called
genre, you have to set an option
default_genre with the term-id of the term you want to protect from being deleted via the admin GUI:
$taxonomy = 'genre';
$key = get_option( 'default_' . $taxonomy );
$term = get_term_by( 'name', 'Your default genre term', $taxonomy );
if ( empty( $key ) && $term )
update_option( $key, $term->term_id );
tl;dr In my first answer I missed this feature. But the description of the capability handling is still valid.
At this point, it is not possible. That is because in
WP_Terms_List_Table all capability checks are made like this:
current_user_can( $tax->cap->delete_terms );
That means, all the view checks is, if the user has the privilege to delete terms by this category overall. It would be possible, if the function call looks like that:
current_user_can( $tax->cap->delete_terms, $tag )
$tag would be the term object.
In this case you could easily filter
map_meta_cap (where the capability check and the second parameter is passed through) to revoke the privilege to delete a specific term.
By the way, this is the default behaviour in
WP_Posts_List_Table, so it's possible to check capabilities for each single post.
The only way I see at the moment is, to register a taxonomy without the default admin UI elements and build a custom admin page to manage the terms by your needs.