Add multiple=”multiple” attribute to categories dropdown

Take a look at the source of wp_dropdown_categories(). It uses walk_category_dropdown_tree() to render the output. Right after that you have a filter named wp_dropdown_cats that allows altering the final MarkUp:

$output = apply_filters( 'wp_dropdown_cats', $output );

You could now use a Regex and preg_replace or parse it using DOMDocument, etc.

Keep in mind that you should change the select elements Name attribute as well – else you wouldn’t be able to save an array. Example:

<select multiple name="foo[]" ...>

Still you’ll need to change the walker argument and rewrite the Walker itself. The reason can be read in Walker_CategoryDropdown::start_el:

if ( $category->term_id == $args['selected'] )
    $output .= ' selected="selected"';

As you can see currently it’s checking only a single value, not an array. So basically you’ll need a check against your array. Example overriding method that checks against an array:

public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
    $pad = str_repeat('&nbsp;', $depth * 3);

    $cat_name = apply_filters('list_cats', $category->name, $category);
    $output .= "<option class=\"level-{$depth}\" value=\"{$category->term_id}\"";

    # >>> HERE WE GO:
    if ( in_array( $category->term_id, $args['selected'] ) )
        $output .= ' selected="selected"';

    $output .= '>';
    $output .= $pad.$cat_name;
    if ( $args['show_count'] )
        $output .= "({$category->count})";
    $output .= "</option>";
}

Put above method in a new class that extends Walker_CategoryDropdown and put that new Walker class as argument into your args array for wp_dropdown_categories():

wp_dropdown_categories( array(
    'walker'   => new Custom_Walker_CategoryDropdown
    'selected' => get_option( 'foo' )
    # etc…
) );

As you can see, I added the option foo, which comes from the name="foo[]" above. The specific implementation is up to you. This answer shall just serve as guide towards your solution.