Since each category (and by the way, you might want to rename either the table or the level so that "category" doesn't mean two different things) has a singular known parent, but an indeterminate number of unknown children, you need to "walk up" from the most specific (at depth = 2) to the most general category, performing a self-join on the category table for each additional value you want to insert.
If you're impatient, skip to the SQL Fiddle link at the bottom of the post. If you'd rather be walked through it, continue reading - it's really not that different from any other case where you have a surrogate ID that you want to replace with data from the corresponding table.
You could start by looking at all the information:
SELECT * FROM products AS P
JOIN
products_categories AS PC ON P.id = PC.product_id
JOIN
categories AS C ON PC.category_id = C.id
WHERE P.id = 1 AN D C.depth = 2;
+----+------------+------------+-------------+----+-----------+-------+---------+
| id | name | product_id | category_id | id | parent_id | depth | name |
+----+------------+------------+-------------+----+-----------+-------+---------+
| 1 | Rad Widget | 1 | 3 | 3 | 2 | 2 | Widgets |
+----+------------+------------+-------------+----+-----------+-------+---------+
First thing you have to do is recognize which information is useful and which is not. You don't want to be SELECT *-ing all day here. You have the first two columns you want, and the last column (recognize this as your "class"); you need parent_id to find the next column you want, and let's hold onto depth just for illustration. Forget the rest, they're clutter.
So replace that * with specific column names, alias "class", and go after the data represented by parent_id. This information is stored in the category table - you might be thinking, but I already joined that table! Don't care; do it again, only give it a new alias. Remember that your ON condition is a bit different - the products_categories has done its job already, now you want the row that matches C.parent_id - and that you only need certain columns to find the next parent:
SELECT
P.id,
P.name,
C1.parent_id,
C1.depth,
C1.name,
C.name AS 'class'
FROM
products AS P
JOIN
products_categories AS PC ON P.id = PC.product_id
JOIN
categories AS C ON PC.category_id = C.id
JOIN
categories AS C1 ON C.parent_id = C1.id
WHERE
P.id = 1
AND C.depth = 2;
+----+------------+-----------+---------------+---------+
| id | name | parent_id | name | class |
+----+------------+-----------+---------------+---------+
| 1 | Rad Widget | 1 | Miscellaneous | Widgets |
+----+------------+-----------+---------------+---------+
Repeat the process one more time, aliasing the column you just added and using the new C1.parent_id in your next join condition:
SELECT
P.id,
P.name,
PC.category_id,
C2.parent_id,
C2.depth,
C2.name,
C1.name AS 'category',
C.name AS 'class'
FROM
products AS P
JOIN
products_categories AS PC ON P.id = PC.product_id
JOIN
categories AS C ON PC.category_id = C.id
JOIN
categories AS C1 ON C.parent_id = C1.id
JOIN
categories AS C2 ON C1.parent_id = C2.id
WHERE
P.id = 1
AND C.depth = 2;
+----+------------+-----------+-------+-------------+---------------+---------+
| id | name | parent_id | depth | name | category | class |
+----+------------+-----------+-------+-------------+---------------+---------+
| 1 | Rad Widget | NULL | 0 | Electronics | Miscellaneous | Widgets |
+----+------------+-----------+-------+-------------+---------------+---------+
Now we're clearly done; we can't join another copy on C2.parent_id = NULL and we also see that depth = 0, so all that's left to do is get rid of the columns we don't want to display and double check our aliases. Here it is in action on SQL Fiddle.