One key function you might need is the (undocumented) function Graphics`Mesh`InPolygonQ[], which tests if a point is inside a given polygon. With it, and a few other tweaks, here's my version of weatherMap[]:
weatherMap[region_String, property_String, res_Integer: 25, opts___] := Module[{fmin, cmax, coords, pts, minLong, maxLong, minLat, maxLat, deltaLong, deltaLat, data}, fmin = Composition[Floor, Min]; cmax = Composition[Ceiling, Max]; coords = CountryData[region, "Coordinates"] /. v_?VectorQ :> Reverse[v]; pts = Flatten[coords, 1]; {minLong, maxLong} = Through[{fmin, cmax}[pts[[All, 1]]]]; {minLat, maxLat} = Through[{fmin, cmax}[pts[[All, 2]]]]; {deltaLong, deltaLat} = {maxLong - minLong, maxLat - minLat}/res; data = Table[WeatherData[{lat, long}, property], {long, minLong, maxLong, deltaLong}, {lat, minLat, maxLat, deltaLat}]; ListContourPlot[data, AspectRatio -> Automatic, DataRange -> {{minLong, maxLong}, {minLat, maxLat}}, Epilog -> {Directive[EdgeForm[Black], FaceForm[None]], Polygon[coords]}, opts, ColorFunction -> "ThermometerColors", Contours -> 10, InterpolationOrder -> 3, PerformanceGoal -> "Quality", RegionFunction -> (Or @@ Map[Function[polys, Graphics`Mesh`InPolygonQ[polys, {#1, #2}]], coords] &)]]
(Not having Mathematica 9, I had to omit the option PlotLegends; you can add it back yourself.)
Test:
weatherMap["USA", "Temperature"]

I should note that I thought it best not to delete Missing[] entries, since ListContourPlot[] is certainly able to cope with them (note the holes in the picture), and I feel it is dishonest to pretend that data exists in regions where there is actually none.
If you want your weather maps to be a bit more accurate, and you don't mind a bit of a wait (WeatherData[] is, after all, rather slow), you can use a DensityPlot[] (similar to what Mark suggested), and let the internal adaptive sampling algorithms do the sampling for you, instead of having to sample at equispaced longitudes/latitudes, and potentially missing data. With this in mind, here is a shorter (but slower) implementation of weatherMap[]:
weatherMap[region_String, property_String, opts___] := Module[{coords, minLong, maxLong, minLat, maxLat}, coords = CountryData[region, "Coordinates"] /. v_?VectorQ :> Reverse[v]; If[VectorQ[CountryData[region, "Countries"], TrueQ], coords = Flatten[coords, 1]]; {{minLong, maxLong}, {minLat, maxLat}} = PlotRange[Graphics[Polygon /@ coords]]; DensityPlot[WeatherData[{lat, long}, property], {long, minLong, maxLong}, {lat, minLat, maxLat}, AspectRatio -> Automatic, MeshFunctions -> {#3 &}, opts, BoundaryStyle -> Directive[Thickness[Medium], Black], ColorFunction -> "ThermometerColors", MaxRecursion -> 1, Mesh -> 10, PerformanceGoal -> "Quality", RegionFunction -> Function[{x, y, z}, Or @@ (Graphics`Mesh`InPolygonQ[#, {x, y}] & /@ coords)]]]
Some new features you might notice include the (undocumented) use of PlotRange[] to reckon out appropriate bounds for the data to be plotted, and the use of MeshFunctions -> {#3 &} so that one could still see the contours where property is constant.
Here again is the temperature map for the United States:
weatherMap["USA", "Temperature"]

The color function can be easily changed, of course:
weatherMap["USA", "Temperature", ColorFunction -> "LightTemperatureMap"]

Here's a demonstration of weatherMap[] on a collection of countries, showing its handling of noncontiguous land masses:
weatherMap["WesternEurope", "Temperature"]

Finally, to demonstrate the use of a "rainbow" map, here's a temperature map of Malaysia:
(* "jet" colormap *) jet[u_?NumericQ] := Blend[{{0, RGBColor[0, 0, 9/16]}, {1/9, Blue}, {23/63, Cyan}, {13/21, Yellow}, {47/63, Orange}, {55/63, Red}, {1, RGBColor[1/2, 0, 0]}}, u] /; 0 <= u <= 1 weatherMap["Malaysia", "Temperature", ColorFunction -> jet]

(On the other hand, there are a number of reasons to avoid rainbow-like color maps for applications like these; see e.g. this and this.)