(add-hook 'after-init-hook ...) is the so-to-say brute-force approach to setting up customizations for packages.
No. If you want to configure packages in your init file, the typical approach is to call
(package-initialize) at the top of the file, and then do the configurations.
after-init-hook is unnecessarily complicated for this purpose.
eval-after-load and its more syntactically sugary
with-eval-after-load seem more appropriate for more dynamic and fine grained configuration that plays well with the gradual, separate and lazy loading of extensions.
(with-)eval-after-load is used for things you want to do after a package is loaded.
package-initialize doesn’t load the packages, it only “prepares” them (loads their autoloads).
If you use
eval-after-load around every set of configurations, you won’t need to call
(package-initialize) at the top. But what people usually do is to call
(package-initialize), so that most configurations can be written straight to the init file, and then only
eval-after-load code which is very long or which depends on the package being loaded.