Why isn’t jQuery 2.1 loading in the header?

In theory the code you wrote should work, in the practical application you are missing some good practices which it might impact on how your code is working, so it’s better run through a bit of troubleshooting to tick off everything from the checklist.

By de-registering jquery you are taking away both the jQuery core and the jQuery Migrate javascripts, probably what are you trying to do is to deregister just the core and keep the jQuery Migrate on.

jQuery Migrate consists in old legacy jQuery code which ports all the functionality of legacy stuff onto the new version of jQuery.

On the same page of the Codex you linked if you scroll down you can find a list of handlers of integrated javascripts you can de-register.

As result you have to to deregister jquery-core instead of jquery to keep some of the functionalities intact, this includes plugins they might some legacy jQuery stuff to run.

You don’t need to append “false” at the last argument since it’s already false by default, I also suggest to drop your protocol, this ensures jQuery will be always served to the browser if you want to switch to https at a later time.

As a final touch, namespacing is very important when you are coding in a big environment where other’s people code runs along with yours. add_scripts() seems a bit too generic for me, if you are writing your function inside the functions.php file try to add the name of your theme, or write something very unique so you are sure the same function doesn’t get collide in the future with a function coming from a plugin or something else in your working files.

add_action( 'wp_enqueue_scripts', 'YOURTHEMENAME_scripts' );

function YOURTHEMENAME_scripts() {
    wp_deregister_script('jquery-core');
    wp_register_script('jquery-core', '//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js', false, '2.1.0');
    wp_enqueue_script('jquery-core');
}

Please note that the loading order of WordPress is the following:

Core -> Plugins -> Theme

If you are trying to de-register jQuery from a custom plugin then possibly your theme is taking over and messing around with the scripts queue.

If after all of this you’re still getting the Javascript into the footer then there’s something horribly wrong going on into your header.php or footer.php files: one of the rookie reasons could be the location of wp_head() and wp_footer() specific hooks in your theme, I’ve seen this so many times which it could be easily a possibility.

wp_head() is a hook which adds for you meta tags, the css queue and the js queue with the last flag argument set to “false”.

wp_footer() is the hook which cares about adding to you the rest of the JS with the last flag argument set to “true” and extra markup generated from various plugins (and for the admin bar from the WP core).

Do a double check about the location of your hook functions, if you have wp_head() in your footer then it could be easily the reason why your javascript queue is being added to the footer.