How do other modules update elements using AJAX callbacks?
Thanks @Tasneem for directing me. I did it as follows:

function hook_form() {
  $form['select_element'] = array(
    '#type' =&gt; 'select',
    '#options' =&gt; $options,
    '#default_value' =&gt; $default,
    '#ajax' =&gt; array(
      'callback' =&gt; 'ajax_callback',
      'wrapper' =&gt; 'block_wrapper',
      'method' =&gt; 'replace',
    ),
  );

  $form['block_wrapper'] = array(
    '#type' =&gt; 'item',
    '#title' =&gt; t('Contents'),
    '#id' =&gt; 'block_wrapper',
    '#markup' =&gt; views_embed_view(...),
  );

  return $form;
}


function ajax_callback($form, $form_state) {
  $form['block_wrapper'] = array(
    '#type' =&gt; 'item',
    '#title' =&gt; t('Contents'),
    '#id' =&gt; 'block_wrapper',
    '#markup' =&gt; views_embed_view(...),
  );

  // Returning the entire $form here made the select element appear twice, so only return the wrapper element.
  return $form['block_wrapper'];
}