I know shells can be uploaded via sql injection, remote file inclusion and exploiting the web app's own upload mechanism. Are there any other ways to upload a shell to a website and be able to execute commands?
You don't just have to be concerned by the ability for the user to upload a shell, but also by what exploitation of your code could achieve the same thing. There are many, many websites out there which use PHP commands such as
Another method in addition to those you mentioned in terms of actual malicious filed upload is the HTTP PUT request.