Мой ответ будет несколько груб и не типичен, однако: "Станьте говнокодером!"
Я не шучу - берите реальные задачи и решайте их как можете - по наитию, по кривым советам из гугла и stackoverflow, но главное - делайте законченные решения, получайте результат который работает.
Любую задачу сначала решайте сами - нужно сделать сортировку - пишите алгоритм и радуйтесь, что он работает. А уже потом - читайте как надо сделать, и только после этого (если почувствуете потребность!) - читайте теорию.
Все книги что вы написали безусловно волшебны и необходимы для отличного программиста, однако без практики они - пыль, которая развеется спустя неделю после прочтения. Поверьте мне, я их все читал :)
Кстати Кнута я бы вычеркнул без раздумий - для его чтения и понимания нужен очень хороший мат-базис и опыт в программировании. Если случиться, что вы будете писать оптимизированные библиотеки для обработки данных на С - тогда и начинайте его читать, очень пригодится, отвечаю )
Пример обучения:
1. Ставим задачу. Пример - написать приложение, которое выводит топ-10 вопросов на Тостере.
2. Разбиваем задачу на проблемы которые надо решить. Пример - развернуть рабочее окружение, понять как сделать "Hi world", как работать с сетью, как парсить HTML
3. Решаем проблемы. В лоб. Задание - на скорость, всё должно быть решено в кратчайшие скроки. Для каждой проблемы используем любое решение которое попалось под руку. Буквально - первое, это важно! То есть реально ковнокодим, забивая на всё - на красоту кода, на оформление, на скорость, лишь бы работало! Девиз этого этапа - херак, херак и в продакшен! Результат этапа - рабочее приложение.
4. Делаем поверхностный анализ. Задача решена? Есть ли косяки которые уже не нравятся? Как их можно решить, исходя из минимального опыта? Локализуем проблемные участки исходя из собственных взглядов. Результат этапа - опыт самостоятельного анализа кода.
5. Делаем глубокий анализ. Пытаемся для каждой задачи подобрать лучшее решение из тех что есть. Читаем теорию о том, как надо делать на самом деле. Изучаем и внедряем паттерны, пытаемся сделать код, который можно переносить в другой проект. Важно не менять условия задачи, вроде "а можно же ещё вывести ответы на вопросы". Не можно, задача должна оставаться прежней. Результат этапа - хороший код и выявленные пробелы в знаниях.
6. Отдыхаем, читая теорию в рамках решённых задача и около них. Результат - теория, подкреплённая практикой.
7. GOTO 1.