unregister a sidebar widget

If the theme or plugin that adds a widget or sidebar is removed, then essentially it’s removed from the system, what is not cleared out on deactivation/removal is widget data that’s stored in the option table(applicable to widgets, not sidebars).

If a sidebar is removed, any widgets that were previously in that sidebar i believe get moved into the inactive widgets group, however i can’t see WP doing any clean up to remove widget data from the options table(one row in the table per widget if you’re curious).

I did a quick test, commented out all my registered sidebars, verified i couldn’t add widgets, i see this on the widget page.

No Sidebars Defined

The theme you are currently using
isn’t widget-aware, meaning that it
has no sidebars that you are able to
change. For information on making your
theme widget-aware, please follow
these instructions.

I then fire up PhpMyAdmin and check the options table, and can see various widget entries still, eg. widget_categories, widget_text and various others.

So it’s my impression that only thing you should ever need to clean up is widget data from widgets that may not exist on the installation anymore, ie. data will remain in the options table even when a widget is no longer registered(i also tested unregistering/removing custom widgets i have, the data remained).

Option data is stored with a key based on the class name of the registered widget(this is declared in the $widget_op variable setup inside constructor function of the given widget class). The keys are basically just prefixed with widget_ and followed by the class name, for example the text widget has the following key in the options table – widget_widget_text.

Correction: The key is derived from this part of the widget class registeration code, but prefixed with widget_ (eg. widget_somename).

$this->WP_Widget('somename', __('Some Name'), $widget_ops, $control_ops);

Of course it’s unlikely you’ll know the name of widgets that get removed from the system, i just wanted to be accurate in how the option key names are determined for widgets.

Hope that helps.

EDIT:
As per my comment on this answer, i wrote a function to output a list of possibly redundant widget entries in the options table.

add_action( 'load-widgets.php', 'check_for_widget_data' );
function check_for_widget_data() {
    add_action( 'admin_notices', 'notify_of_redundant_widgets' );
}
function notify_of_redundant_widgets() {
    global $wp_registered_widgets, $wpdb;
    $names= array();
    foreach( $wp_registered_widgets as $instance_key => $data )
        $names[] = $data['callback'][0]->option_name;

    $names = array_unique($names);

    $stored = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'widget_%'");

    sort($names);
    sort($stored);
    $diff = array_diff( $stored, $names );
    if( empty( $diff ) )
        return;

    echo '<div class="updated"><p><strong>Looks like there\'s some left over widget data in the options table.</strong><br />The following rows may now be redundant.<br />';
    echo '<ul><li>&bull; '. implode( '</li><li>&bull; ', $diff ) . '</li>';
    echo '</p></div>';
}

Posted incase it’s useful to someone..