For notational convenience, let M′ be the dual of M, i.e. the homomorphisms from M into R. Let T be the tensor product M′×W. Build a canonical map j from T into hom(M,W) as follows. Given f,y in M′ cross W, multiply f by y to obtain a function in hom(M,W). This is a bilinear map, and by the universality of the tensor product, it implies a compatible map j from T into hom(M,W).
Think of j as multiplying a function from M into R by y in W. The result is a module homomorphism from M into W. Thus j maps T into hom(M,W). Since j comes from a bilinear map, it is a module homomorphism on T. We just need to know when j is an isomorphism.
Assume j is an isomorphism for every W. Consider an arbitrary short exact sequence 0 → A → B → C → 0 and tensor this with M′. Recall that dual M is flat. Thus the resulting sequence is short exact.
Start with the middle module M′ tensor B, and build the homomorphism jB into hom(M,B). We know this is an isomorphism. Build similar isomorphisms jA and jC onto hom(M,A) and hom(M,C) respectively.
If f embeds A into B, and g maps B onto C, then f and g induce functions from hom(M,A) into hom(M,B), and from hom(M,B) into hom(M,C). Verify that this diagram commutes. Move forward along the lower sequence, then up an isomorphism; that is the same as moving up an isomorphism and forward along the upper sequence. Similarly, you can move forward and down, or down and forward. With this in hand, the sequence of duals becomes exact, just as the sequence of tensor products is exact. Our original exact sequence produces an exact dual, and this happens for every short exact sequence. Therefore M is projective .
Approach the converse by setting M = R. The dual of M is now R, as 1 maps to anything in R. Tensor with W and T is isomorphic to W. At the same time, hom(R,W) = W, as 1 maps to anything in W. Our homomorphism j maps T onto hom(R,W) by carrying y to y. It's just a copy of W either way.
Now assume M is free of finite rank. Remember that dual and tensor product both commute with a finite direct product. Therefore T and hom(M,W) both look like n copies of W running in parallel. The map j simply fixes the tuple in Wn, and is an isomorphism.
Finally let M be projective, a summand of the free module F, with F = M*U. Build T from F, and j is an isomorphism on T. Yet T is a direct product, based on M′×W and U′×W. At the same time, hom(F,W) = hom(M,W)*hom(U,W). Restrict the domain to either summand, and the image lies in the corresponding summand of the range. In both cases the restriction has to be an isomorphism. Therefore hom(M,R)×W = hom(M,W) for every W.
This part of the proof requires M to be projective and finitely generated. Thus M is the summand of a free R module of finite rank, which I called F in the above paragraph. Dual does not commute with an infinite direct sum. If we want to write hom(Rn,W) = hom(R,W)n, n has to be finite, where direct sum and direct product are synonymous.