It's actually fairly simple,
w just skips to the next word, but any sort of punctuation or whitespace breaks up words.
W is like the industrial-strength next-word command, words are only delimited by whitespace, be it tab, space or newline.
w stops at the delimiting punctuation also, in case you want to deal with that.
I find the difference useful most often with hostnames:
birdman.cartoons.fictional.com # Fictional host
w, you stop on each part of the hostname and the dots.
W just skips the entire hostname and goes onto the
#. These both also apply to
c for deleting and changing words.
If positioned at the beginning of the above line, if you wanted to replace
birdman.cartoons with something else, you would use
3cw to replace both of the first two parts and the dot in the middle. You couldn't do it with
W without retyping the whole hostname.