How can I limit the exposed filters to only display values for which content exists? We have a view for the Basic page content type, which has a Category field that allows to enter multiple values.
All values for Category are displayed (IoT, Cloud, Security), but there are only nodes that use IoT and Cloud. I want to display only IoT and Cloud for the Category exposed filter.

How can I limit the exposed filters to only display values for which content exists?

The view settings are the following.

Format


Show: Content | Teaser
Format: Unformatted List | Settings


Filter Criteria


Authored on (exposed)
Category (field_category) (exposed) | Settings (settings is set to Category tag, selection type = Dropdown)
Author (exposed) 
Published (= Yes)
Content Type (= Basic Page)


Sort Criteria


Content: Authored on (desc)


Contextual Filters, Relationship


None


Exposed form


Exposed form style: Better Exposed Filters | Settings
Settings are set to default in Better Exposed Filters


Other


Use Ajax: Yes
Use aggregation: no
query settings: default settings


Here is what we tried. This only gets me the nodes that have a value for field_category and all term values for categories term individually. 

function mymodule_form_views_exposed_form_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  $node_storage = Drupal::getContainer()-&gt;get('entity_type.manager')-&gt;getStorage('node');
  $node_ids = $node_storage-&gt;getQuery();

  // This returns all nodes with a value for *field_category*. 
  $nodes = $node_ids-&gt;condition('type','page')
    -&gt;exists('field_category')
    -&gt;condition('status', 1)
    -&gt;sort('title')
    -&gt;execute();

  // returns all taxonomy terms. 
  $category_tree = \Drupal::entityTypeManager()-&gt;getStorage('taxonomy_term')-&gt;loadTree('categories');

}
This works for me:

function mymodule_form_views_exposed_form_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if (isset($form['tid']['#options'])) {
    foreach ($form['tid']['#options'] as $key =&gt; $value) {
      // Limit to numeric keys to exclude the 'All' option.
      if (is_numeric($key)) {
        // Start database query.
        $query = \Drupal::database()-&gt;select('taxonomy_index', 'ti');
        $query-&gt;fields('ti', ['nid']);
        $query-&gt;condition('ti.tid', $key);
        $nodes = $query-&gt;execute()-&gt;fetchAssoc();
        // Remove option if term has no instance.
        if (!$nodes) {
          unset($form['tid']['#options'][$key]);
        }
      }
    }
  }
}


You will probably need to adjust the 'tid' in $form['tid']['#options'] to the Filter identifier as defined in your views' filter settings.
Credits for the quick and efficient database query go to https://drupal.stackexchange.com/a/219368/25154.