Index: src/js/_enqueues/admin/common.js
===================================================================
--- src/js/_enqueues/admin/common.js	(revision 43556)
+++ src/js/_enqueues/admin/common.js	(working copy)
@@ -110,8 +110,9 @@
 	 * @returns {string} The hidden column names separated by a comma.
 	 */
 	hidden : function() {
-		return $( '.manage-column[id]' ).filter( ':hidden' ).map(function() {
-			return this.id;
+		//Checking for unchecked column names is better and more robust than checking for hidden column headers
+		return $( '.hide-column-tog' ).filter(':not(:checked)' ).map(function() {
+			return this.value;
 		}).get().join( ',' );
 	},
 
Index: src/wp-admin/includes/ajax-actions.php
===================================================================
--- src/wp-admin/includes/ajax-actions.php	(revision 43556)
+++ src/wp-admin/includes/ajax-actions.php	(working copy)
@@ -1573,7 +1573,9 @@
 		wp_die( -1 );
 	}
 
+	$special = get_special_columns(); //get list of special columns that are not meant to be hidden
 	$hidden = ! empty( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
+	$hidden = array_diff($hidden, $special); //remove the special columns from the list of columns to be hidden
 	update_user_option( $user->ID, "manage{$page}columnshidden", $hidden, true );
 
 	wp_die( 1 );
Index: src/wp-admin/includes/class-wp-screen.php
===================================================================
--- src/wp-admin/includes/class-wp-screen.php	(revision 43556)
+++ src/wp-admin/includes/class-wp-screen.php	(working copy)
@@ -1071,7 +1071,7 @@
 		<fieldset class="metabox-prefs">
 		<legend><?php echo $legend; ?></legend>
 		<?php
-		$special = array( '_title', 'cb', 'comment', 'media', 'name', 'title', 'username', 'blogname' );
+		$special = get_special_columns(); //get list of special columns that are not meant to be hidden
 
 		foreach ( $columns as $column => $title ) {
 			// Can't hide these for they are special
Index: src/wp-admin/includes/screen.php
===================================================================
--- src/wp-admin/includes/screen.php	(revision 43556)
+++ src/wp-admin/includes/screen.php	(working copy)
@@ -240,3 +240,23 @@
 function set_current_screen( $hook_name = '' ) {
 	WP_Screen::get( $hook_name )->set_current_screen();
 }
+
+/**
+ * Get a list of special columns.
+ *
+ * @since X.Y.Z
+ *
+ * @return array
+ */
+function get_special_columns() {
+	$special = array( '_title', 'cb', 'comment', 'media', 'name', 'title', 'username', 'blogname' );
+
+	/**
+	 * Filters the list of special columns.
+	 *
+	 * @since X.Y.Z
+	 *
+	 * @param array     $special An array of special columns.
+	 */
+	return apply_filters( 'special_columns', $special );
+}
