You can use a subquery anywhere that a table is allowed and you're just reading the table, such as the FROM or JOIN clauses. This is called a derived table. That's your third example. Since it has to be only for reading, you can't use it as the target for UPDATE or DELETE (but you can join with a subquery in an UPDATE or DELETE query).
You can use a subquery anywhere that an expression is allowed. The subquery has to select a single value and must return at most one row (if it returns now rows it evaluates to NULL). A restriction is that you can't use a subquery in the WHERE clause of an UPDATE or DELETE query that's targeted to the same table; in that cause you have to join with the subquery (see You can't specify target table for update in FROM clause).
This means that a subquery can be used in the SELECT list, in the WHERE clause, and in the HAVING clause. Even in the ON clause, although I've rarely seen examples of this.
You can use a subquery as in place of the list of values in an IN expression, e.g.
SELECT Salary
FROM Employee
WHERE id in (SELECT Emp_id FROM Employee_Department WHERE Dept_id = 100)
However, in my experience MySQL often optimizes these poorly, and they're better written as joins:
SELECT e.Salary
FROM Employee AS e
JOIN Employee_Department AS d ON e.id = d.emp_id
WHERE d.dept_id = 100;
A SELECT query can also be used as the source of data in an INSERT query:
INSERT INTO low_salary_employees
SELECT employee_id
FROM Employee
WHERE Salary < (SELECT MAX(Salary)/10 FROM Employee)