What's the difference between the terms "Shell" and "Bash"?
A "shell" is any software that provides an interface to an operating system. For instance, explorer.exe is the default shell in Windows (though alternatives exist), and on OS X Finder provides much of the same functionality. On Linux/*nix, the shell could be part of the desktop environment (like Gnome or KDE), or can be a separate software component sitting on top of it (like Unity or Cinnamon).
The above examples are all graphical shells that use a combination of windows, menus, icons and other such elements to provide a graphical user interface (GUI) that can be interacted with using the mouse cursor. However, in the context of software like Bash, or writing scripts, "shell" is usually taken to mean a command-line interpreter, which performs largely the same duties as a graphical shell, except is entirely text-based.
Bash is a specific example of a command-line shell, and is probably one of the most well-known ones, being the default in many Linux distributions as well as OS X. It was designed as a replacement for the Bourne shell (Bash stands for "Bourne again shell"), one of the first Unix shells.
Examples of command-line shells on Windows include cmd.exe (aka Command Prompt) and PowerShell.
Bash is one of several shells.
A shell on a Unix or Unix-like system like OSX or Linux is a application program that provides a command-line interface to the operating system, allowing you to type commands and run them. There are a number of different shells to choose from but they all provide filename wildcarding, piping, here documents, command substitution, variables and control structures for condition-testing and iteration.
The original Unix shell was the Bourne shell, sh, written by Stephen Bourne at Bell Labs. Then came the C shell, written by Bill Joy at Berkeley, since updated as tcsh. Other shells include the Korn shell, ksh, written by David Korn, also at Bell Labs, and bash, the "Bourne again shell", written by Brian Fox for the GNU project as a free replacement for sh.
Today, bash is probably the most popular Unix shell but a lot of people (me included) still prefer the C shell based on (what to some of us seems like) its nicer syntax. Basically, it's a matter of taste, so I recommend reading the Wikipedia articles I've linked to help you get started.
The term 'shell' is well named. It is literally a shell around the O/S allowing the user to interact with the computer. When it was originally conceived there were very little if any graphical user interfaces (no windows :( ). Everything was done on the command line. But even the command line needed a place to live. It lived, and still does, in a shell.
In simple terms, in order for the command line to be useful it needed instructions that it could call. So programs were made to run inside the shell for the command line to use. The programs were grouped tightly in their own packages, and intended to work together. They include programs like "ls" and "grep", "ps", "sed", etc. They also include file redirection commands like ">" and "<" and pipes ("|"). More importantly they also include programming constructs like conditional operations (if, then, else, for loops, while loops, ways to check the status returned when you run a statement (e.g. if you run "ls" did it find anything?), thing like that). These are the foundations of more complex command line (shell) scripts, and in fact is what the command line interpreter is.
When someone uses the term 'Bash Shell' they are talking about a command line interpreter called 'Bash' that runs in the O/S shell. You could think of it as being short for 'Bash Shell Interpreter'. There are other interpreters like Bourne (Bash is a 'new and improved Bourne Shell and it is short for Bourne Again Shell). There is also the C-Shell, the K-Shell (favoured by many who write complex shell scripts), and other GNU variants. Over the years it has become customary to refer to the particular command line interpreter you are using as the shell because one can't be used without the other. But the reality is that they are different.
As to why they are properly known as command line interpreters and not as the actual shell: it is because they live in the shell and interpret all commands as if they were running in a program. And the shell doesn't care what interpreter you run in it, as long as it meets the correct standards.
And as to why they are called interpreters, it is because they are really interpreters. Even if you are not explicitly running a script (and a script is really just a text file of commands you create so that you can execute the same commands over and over without having to type them in again). For example, take the humble 'ls' command. When you run it, it returns a list of files. But how it runs is more important to your question: It actually runs inside the context of the command line interpreter, even if you just run what appears to be a simple one off command. That is, it runs as if it were a statement in part of a bigger program. It runs as if it were in a shell script script file without actually being in a shell script file. An anonymous shell script file as it were.
Anything you run on the command line has this in common (whether it be a single command like 'ls' or a script file full of commands and iterators and conditional statements): it is all processed by the command line interpreter; be it Bash, C-Shell, K-Shell (default on AIX btw).
To see what I mean, make a directory 'test':
mkdir test
Enter it and run the folowing commands
grep hello *
You will get some sort of response like 'no such file or directory'. Now enter the command
echo $?
($? says, tell me what you found in cryptic computer speak.) You should see it return a number (it should be) '2'. That is the return code from grep that means 'no such file or directory'. Now run the following:
echo hello > hello.txt
grep hello *
echo $?
You will see the file 'hello.txt' returned from the initial grep command and should now see the 'echo $?' return the number '0' meaning it actually found something.
Even if these seemingly one off commands are run, the command line interpreter acts like they are part of a larger program and keeps track of their return values. That is why if you forget the * at the end of the grep command it doesn't return. It is knows the statement is incomplete and expects more input. After all you could conceivably be going to ask it to grep the results of some loop which is perfectly legal to write and run on the command line.
Bottom line is the shell is the shell, and the interpreter (whatever the name of the one you use, 'Bash', k-shell, etc.) are different. But often they are used interchangeably, because at any given instant they are completely tied together.