Get field definitions across bundles, including base fields
The more I look, the more confusing and complex this entire architecture looks to me.


The architecture is actually very similar to 7.x, just renamed. 7.x had fields and field instances, 8.x has field storages (= 7.x fields) and fields. Base fields are exposed as both by default, while configurable fields have a separate entity type for each.

Field storages exist per entity type and fields per entity_type/bundle. (in 7.x, fields were global, otherwise it is the same).

To get all field storages of an entity type, you can use \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions(). Note that a field storage has no label, only the field (and the label can be different per bundle), so you will need to consider all bundles anyway if you don't want to just show a machine name. token and views have helper functions for that, e.g. _token_field_label().

Another useful reference is how the entity selection plugin build the list of fields to sort by: \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection::buildConfigurationForm()