It sounds like your experience is significantly different from mine, and from several of the other commentators here.
I don't know anyone who prefers
memcpy(&a, &b, sizeof(a));
over
a = b;
In my programming world (and in just about any world I can imagine), simple assignment is vastly preferable to memcpy. memcpy is for moving chunks of arbitrary data around (analogous to strcpy, but when it's arbitrary bytes instead of null-terminated strings). It's hard to imagine why anyone would advocate using memcpy instead of struct assignment. Naturally there are individual programmers everywhere who have gotten into various bad habits, so I guess I can't be too surprised if there are some who prefer the opposite, but I have to say, I would generally disagree with what they're doing.
Someone speculated in the comments that there was perhaps some historical precedent at work, but at least for the memcpy-versus-assignment questions, I can state with some certainty that this is not the case.
Once upon a time, before there was C90 memcpy, there was BSD bcopy, but before there was bcopy there wasn't a standard function for doing an efficient copy of a bunch of bytes from point a to point b. But there was struct assignment, which really has been in the language almost from the beginning. And struct assignment typically uses a nice, tight, compiler-generated byte-copying loop. So there was a time when it was fashionable to do something like this:
#define bcpy(a, b, n) (*(struct {char x[n];} *)a = *(struct {char x[n];} *)b)
I may have gotten the syntax wrong, but this hijacks the compiler's ability to do efficient struct assignment, and repurposes it to copy n bytes from arbitrary pointer b to arbitrary pointer a, i.e. just like bcopy or memcpy.
In other words, it's not like memcpy came first, followed by struct assignment -- it was actually exactly the opposite!
Now, memset versus struct initialization is a different story.
Most of the "clean" ways of zeroing a struct are initializations, but of course it's not uncommon to want to set a struct to all zero at some point later than when it was defined. It's also not uncommon to have a dynamically-allocated struct, and using malloc/realloc rather than calloc. So in those cases, memset is attractive. I think modern C has struct constants you can use at any time, but I'm guessing I'm not the only one who still hasn't learned them and so is still tending to use memset instead.
So I wouldn't consider using memset to be poor style, not in the same way as memcpy is poor style for struct assignment.
Although I have seen, and written, code that did something like
struct s zerostruct = { 0 };
and then later
a = zerostruct;
as a "better style" alternative to
memset(&a, 0, sizeof(a));
Bottom line: I wouldn't agree that memcpy is recommended over struct assignment, and I am critical of anyone who prefers it. But memset is quite useful (and not disrecommended) for zeroing structures, because the alternatives aren't nearly as compelling.