I don't know how deep your mathematical background is, but I hope you can make some sense of my answer. What is your situation: Your function $b$ is a matrix product $Wa$, and you want to compute the derivatives with respect to the matrix $W$ and with respect to the vector $a$. Your second calculation $\frac{\partial b}{\partial a}$ is correct: The Jacobian is just the matrix $W$.
The first part, calculating the derivative with respect to $W$, is a bit more "tricky", as you are no longer viewing your function $b$ going from $\mathbb R^3 \to \mathbb R^3$, but rather from $\mathbb R^{3\times 3}\to \mathbb R^3$ (you're sticking in a matrix and getting out a vector). So writing down the derivative $\displaystyle \frac{\partial{b}}{\partial W}$ can no longer be written in matrix form. What comes into play here is the notion of a "tensor", which you will probably have read about when reading about machine learning subjects. A tensor is softly speaking a generalization of the matrix / vector notation, and you can think about it from a programming perspective as a multidimensional array.
An example: Consider having 100 images, each of which has 50 times 60 resolution where each pixel has some red-color value between 0 and 255. In order to store the color information about all pixels in a meaningful way, you would introduce a $(100,50,60,256)$-tensor, where the $(k,l,m,n)$-entry is the red-value (this is $n$) of the $(l,m)$-th pixel of the $k$-th image. Does that make sense? I hope so. If you come from a programming background you will probably have used something like that.
Now in your case of the Jacobian $\displaystyle \frac{\partial{b}}{\partial a}$ we store the information of the partial derivatives in the same way: it is a $(3,3)$-tensor, where the $(i,j)$-th entry is exactly $\displaystyle \frac{\partial b_i}{\partial a_j}$: This is your matrix $W$ then in the example above, as you have already correctly calculated.
We generalize this notion to $\displaystyle \frac{\partial b}{\partial W}$ accordingly: You put in a $(3,3)$-tensor (in your case $W$) and get out a $(3)$-tensor (your three-dimensional vector $Wa$). Hence $\displaystyle \frac{\partial b}{\partial W}$ is a $(3,3,3)$-tensor, where you have in the $(i,j,k)$-th entry: $\displaystyle \frac{\partial b_i}{\partial W_{jk}}$. I hope you see now why you can no longer note this down in matrix notation: It's more like a cube. Now let's see how $\displaystyle \frac{\partial b_i}{\partial W_{jk}}$ actually looks like.
The $i$-th entry of the vector $b$ is given by:
$$b_i = \sum_{l = 1}^{3}W_{il}a_l.$$
If you differentiate this with respect to $W_{jk}$ you see that
$$\frac{\partial b_i}{\partial W_{jk}} = \begin{cases}
0, & \text{if } i \neq j \\
a_k, & \text{otherwise.}
\end{cases}$$
Hence your tensor will look quite sparse.
I hope that this helps a bit in understanding backpropagation. Applying the chain rule to "tensor-derivatives" works then exactly the same way as the usual chain rule you might know from multivariate calculus, you just have more axes that you're multiplying and summing over. Multiplications like that are for example implemented in functions like tensordot
in the Python library numpy
.